//package com.yunhe.common.service.base.impl;
//
//import com.yunhe.common.client.AuthorityClient;
//import com.yunhe.common.client.DeviceClient;
//import com.yunhe.common.client.MeasRealtimeClient;
//import com.yunhe.common.constant.CacheConsts;
//import com.yunhe.common.domain.base.AbnormalType;
//import com.yunhe.common.domain.base.AlarmLevel;
//import com.yunhe.common.domain.base.AlarmStatus;
//import com.yunhe.common.exception.ArgumentErrorException;
//import com.yunhe.common.exception.ObjectNotFoundException;
//import com.yunhe.common.exception.UniqueConstraintsException;
//import com.yunhe.common.mapper.base.AbnormalTypeMapper;
//import com.yunhe.common.mapper.base.AlarmLevelMapper;
//import com.yunhe.common.mapper.base.AlarmStatusMapper;
//import com.yunhe.common.model.PageParam;
//import com.yunhe.common.model.authority.StationDTO;
//import com.yunhe.common.model.base.AbnormalTypeDTO;
//import com.yunhe.common.model.base.AlarmLevelDTO;
//import com.yunhe.common.model.base.AlarmStatusDTO;
//import com.yunhe.common.model.base.PointDataType;
//import com.yunhe.common.model.device.Analog;
//import com.yunhe.common.repository.base.AlarmStatusRepository;
//import com.yunhe.common.repository.device.impl.AlarmStatusDeviceRepositoryDao;
//import com.yunhe.common.service.base.AlarmLevelService;
//import com.yunhe.common.service.base.AlarmStatusService;
//import com.yunhe.common.service.base.AlarmTypeService;
//import com.yunhe.common.util.QueryUtil;
//import com.yunhe.common.util.StringUtil;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
//import org.springframework.data.domain.PageImpl;
//import org.springframework.data.domain.Pageable;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.lang.reflect.Field;
//import java.util.*;
//
///**
// * 告警规则Service
// * @desc 告警规则服务类实现
// * @author duanxiaoyong
// */
//@Service
//public class AlarmStatusServiceImpl implements AlarmStatusService {
//
//    @Autowired
//    private AlarmStatusRepository alarmStatusRepository;
//    @Autowired
//    private AlarmTypeService alarmTypeService;
//    @Autowired
//    private AlarmLevelService alarmLevelService;
//    @Autowired
//    private AlarmStatusDeviceRepositoryDao alarmStatusDeviceRepositoryDao;
//    @Autowired
//    private DeviceClient deviceClient;
//    @Autowired
//    private MeasRealtimeClient measRealtimeClient;
//    @Autowired
//    private AlarmStatusMapper alarmStatusMapper;
//    @Autowired
//    private AlarmLevelMapper alarmLevelMapper;
//    @Autowired
//    private AbnormalTypeMapper abnormalTypeMapper;
//    @Autowired
//    private AuthorityClient authorityClient;
//
//
//    /**
//     * 告警规则对象处理和判断
//     * @param alarmStatus 告警规则对象
//     */
//    private void processBeforeSave(AlarmStatus alarmStatus)
//            throws ArgumentErrorException, UniqueConstraintsException {
//        //判断告警规则代码、编号、标题是否为空
//        if (StringUtil.isEmpty(alarmStatus.getName()) || StringUtil.isEmpty(alarmStatus.getTitle())) {
//            throw new ArgumentErrorException("告警规则标题、编号不能为空");
//        }
//        //判断告警规则代码是否已存在
////        AlarmStatusDTO typeByCode = this.findByCode(alarmStatus.getCode());
////        if (typeByCode != null) {
////            if (alarmStatus.getId() == null || typeByCode.getId().longValue() != alarmStatus.getId().longValue()) {
////                throw new UniqueConstraintsException("该告警规则代码已存在");
////            }
////        }
//        //判断告警规则编号是否已存在
//        AlarmStatusDTO typeByName = this.findByName(alarmStatus.getName());
//        if (typeByName != null) {
//            if (alarmStatus.getId() == null || typeByName.getId().longValue() != alarmStatus.getId().longValue()) {
//                throw new UniqueConstraintsException("该告警规则编号已存在");
//            }
//        }
//        //如果序号为空，则默认为代码
//        if (alarmStatus.getSn() != null && alarmStatus.getCode() != null) {
//            alarmStatus.setSn(alarmStatus.getCode());
//        }
//        AbnormalType abnormalType = alarmStatus.getAbnormalType();
//        if (abnormalType != null && abnormalType.getId() != null) {
//            AbnormalTypeDTO abnormalTypeById = alarmTypeService.findByAlarmTypeId(abnormalType.getId());
//            alarmStatus.setAbnormalType(abnormalTypeMapper.from(abnormalTypeById));
//        }
//        AlarmLevel alarmLevel = alarmStatus.getAlarmLevel();
//        if (alarmLevel != null && alarmLevel.getId() != null) {
//            AlarmLevelDTO alarmLevelById = alarmLevelService.findById(alarmLevel.getId());
//            alarmStatus.setAlarmLevel(alarmLevelMapper.from(alarmLevelById));
//        }
//        StationDTO station = authorityClient.getStationByStationId(alarmStatus.getStationId()).getBody().getResults();
//        if (station != null) {
//            alarmStatus.setStationTitle(station.getTitle());
//        }
//        PointDataType pointDataType = alarmStatus.getPointDataType();
//        if (pointDataType != null && pointDataType.getId() != null) {
//            PointDataType pointDataTypeById = deviceClient.getPointDataTypeById(pointDataType.getId()).getBody().getResults();
//            alarmStatus.setPointDataType(pointDataTypeById);
//        }
//    }
//
//
//    /**
//     * 新增告警规则
//     * @param alarmStatus 告警规则对象
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public AlarmStatusDTO createAlarmStatus(AlarmStatus alarmStatus)
//            throws ArgumentErrorException, UniqueConstraintsException {
//        alarmStatus.setId(null);
//        processBeforeSave(alarmStatus);
//        AlarmStatus result = alarmStatusRepository.save(alarmStatus);
//        return alarmStatusMapper.to(result);
//    }
//
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public List<AlarmStatusDTO> createAlarmStatus(List<AlarmStatus> alarmStatusList)
//            throws ArgumentErrorException, UniqueConstraintsException {
//        List<AlarmStatus> resultList = new ArrayList<>();
//        for (AlarmStatus alarmStatus : alarmStatusList) {
//            processBeforeSave(alarmStatus);
//            AlarmStatus result = alarmStatusRepository.save(alarmStatus);
//            resultList.add(result);
//        }
//        return alarmStatusMapper.to(resultList);
//    }
//
//    /**
//     * 删除告警规则
//     * @param alarmStatusId 告警规则ID
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public void deleteAlarmStatus(Long alarmStatusId) {
//        alarmStatusRepository.deleteById(alarmStatusId);
//    }
//
//    /**
//     * 更新告警规则（更新全部字段）
//     * @param alarmStatus 告警规则对象
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public AlarmStatusDTO updateAlarmStatus(AlarmStatus alarmStatus)
//            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
//        boolean exists = alarmStatus.getId() != null && alarmStatusRepository.existsById(alarmStatus.getId());
//        if (!exists) {
//            throw new ObjectNotFoundException("找不到ID为" + alarmStatus.getId() + "的告警规则");
//        }
//        processBeforeSave(alarmStatus);
//        AlarmStatus newAlarmStatus = alarmStatusRepository.save(alarmStatus);
//        return alarmStatusMapper.to(newAlarmStatus);
//    }
//
//    /**
//     * 更新告警规则（更新指定字段）
//     * @param alarmStatusId 告警规则ID
//     * @param code 代码
//     * @param name 编号
//     * @param title 标题
//     * @param sn 排序序号
//     * @param activity 是否可用
//     * @param bit 警告位
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public AlarmStatusDTO updateAlarmStatus(Long alarmStatusId,
//                                         Optional<Long> code,
//                                         Optional<String> name,
//                                         Optional<String> title,
//                                         Optional<Long> sn,
//                                         Optional<Boolean> activity,
//                                         Optional<Long> bit,
//                                         Optional<String> devTitle,
//                                         Optional<String> condition,
//                                         Optional<Boolean> alarm,
//                                         Optional<Double> limitValue,
//                                         Optional<Long> stationId,
//                                         Optional<Long> alarmTypeId,
//                                         Optional<Long> alarmLevelId)
//            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException {
//        AlarmStatus alarmStatus = alarmStatusRepository.findById(alarmStatusId).orElse(null);
//        if (alarmStatus == null) {
//            throw new ObjectNotFoundException("找不到ID为" + alarmStatusId + "的告警规则");
//        }
//        code.ifPresent(alarmStatus::setCode);
//        name.ifPresent(alarmStatus::setName);
//        title.ifPresent(alarmStatus::setTitle);
//        sn.ifPresent(alarmStatus::setSn);
//        activity.ifPresent(alarmStatus::setActivity);
//        bit.ifPresent(alarmStatus::setBit);
//        devTitle.ifPresent(alarmStatus::setDevTitle);
//        condition.ifPresent(alarmStatus::setCondition);
//        alarm.ifPresent(alarmStatus::setAlarm);
//        limitValue.ifPresent(alarmStatus::setLimitValue);
//        stationId.ifPresent(alarmStatus::setStationId);
//        if (alarmTypeId.isPresent()) {
//            AbnormalType abnormalType = abnormalTypeMapper.from(alarmTypeService.findByAlarmTypeId(alarmTypeId.get()));
//            alarmStatus.setAbnormalType(abnormalType);
//        }
//        if (alarmLevelId.isPresent()) {
//            AlarmLevel alarmLevel = alarmLevelMapper.from(alarmLevelService.findById(alarmLevelId.get()));
//            alarmStatus.setAlarmLevel(alarmLevel);
//        }
//        processBeforeSave(alarmStatus);
//        AlarmStatus result = alarmStatusRepository.save(alarmStatus);
//        return alarmStatusMapper.to(result);
//    }
//
//    /**
//     * 根据ID获得告警规则对象
//     * @param id 状态ID
//     */
//    @Override
//    public AlarmStatusDTO findByAlarmStatusId(Long id) {
//        AlarmStatus result = alarmStatusRepository.findById(id).orElse(null);
////        processBeforeTransmit(result);
//        return alarmStatusMapper.to(result);
//    }
//
//    /**
//     * 根据代码获得告警规则对象
//     * @param code 代码
//     */
//    @Override
//    public AlarmStatusDTO findByCode(Long code) {
//        AlarmStatus result = alarmStatusRepository.findByCode(code);
//        return alarmStatusMapper.to(result);
//    }
//
//    /**
//     * 根据编号获得告警规则对象
//     * @param name 编号
//     */
//    @Override
//    public AlarmStatusDTO findByName(String name) {
//        AlarmStatus result = alarmStatusRepository.findByName(name);
////        processBeforeTransmit(result);
//        return alarmStatusMapper.to(result);
//    }
//
//    @Override
//    public AlarmStatusDTO findById(Long id) {
//        AlarmStatus result = alarmStatusRepository.findById(id).orElse(null);
//        return alarmStatusMapper.to(result);
//    }
//
//    /**
//     * 获得全部告警规则对象
//     */
//    @Override
//    @Cacheable(value = CacheConsts.Region.ALARM_STATUS,
//            key = "{T(com.yunhe.common.consts.AlarmStatusKey).getKey(#stationIds, #queryStr, #pageParam, T(com.yunhe.common.i18n.LanguageHolder).LANGUAGE_HOLDER.get())}")
//    public Iterable<AlarmStatusDTO> findAlarmStatus(List<Long> stationIds, String queryStr, PageParam pageParam) {
//        List<String> sortList = pageParam.getSort();
//        if (sortList == null) {
//            sortList = new ArrayList<>();
//            sortList.add("-sn");
//        } else if (sortList.size() == 0) {
//            sortList.add("-sn");
//        }
//        Map<String, Object> map = alarmStatusDeviceRepositoryDao.getAlarmStatus(stationIds, queryStr, pageParam.getPage(), pageParam.getSize(), sortList);
//        List<AlarmStatus> results = (List<AlarmStatus>) map.get("result");
//        Long count = ((Number) map.get("count")).longValue();
//        if (QueryUtil.needPaging(pageParam)) {
//            Pageable pageable = QueryUtil.getPageRequest(pageParam);
//            return new PageImpl<>(alarmStatusMapper.to(results), pageable, count);
//        } else {
//            return alarmStatusMapper.to(results);
//        }
//    }
//
////    /**
////     * 根据代码绑定告警类型
////     * @param code 代码
////     * @param alarmTypeCode 告警类型代码
////     */
////    @Transactional
////    public void bindAlarmTypeByCode(Long code, Long alarmTypeCode)
////            throws DatabaseProcessException {
////        alarmStatusRepository.bindAlarmTypeByCode(code, alarmTypeCode);
////    }
////
////    /**
////     * 根据代码解绑告警类型
////     * @param code 代码
////     * @param alarmTypeCode 告警类型代码
////     */
////    @Transactional
////    public void unbindAlarmTypeByCode(Long code, Long alarmTypeCode)
////            throws DatabaseProcessException {
////        alarmStatusRepository.unbindAlarmTypeByCode(code, alarmTypeCode);
////    }
////
////    /**
////     * 更新告警规则（根据代码）
////     * @param code 代码
////     * @param alarmTypeCodes 告警类型代码
////     */
////    public void updateAlarmTypeByCode(Long code, List<Long> alarmTypeCodes)
////            throws DatabaseProcessException {
////        alarmStatusRepository.unbindAllAlarmTypeByCode(code);
////        if (alarmTypeCodes != null && alarmTypeCodes.size() > 0) {
////            alarmStatusRepository.unbindAllAlarmTypeByCode(code);
////            for (Long alarmTypeCode : alarmTypeCodes) {
////                alarmStatusRepository.bindAlarmTypeByCode(code, alarmTypeCode);
////            }
////        }
////    }
//
//    /**
//     * 根据点号获取告警规则
//     * @param pointNumberList 点号列表
//     */
//    @Override
//    public Map<Long, List<String>> getAlarmStatusByPointNumber(List<Long> pointNumberList)
//                throws ObjectNotFoundException {
//        Map<Long, Double> map = measRealtimeClient.getMeasureRealtime(pointNumberList).getBody().getResults();
//        Map<Long, List<String>> results = new HashMap<>();
//        AbnormalTypeDTO alarmType;
//        for (Map.Entry<Long, Double> entry : map.entrySet()) {
//            Long pointNumber = entry.getKey();
//            Analog analogs = deviceClient.getAnalogByPointNumber(pointNumber).getBody().getResults();
//            if (analogs == null) {
//                throw new ObjectNotFoundException("找不到点号" + pointNumber + "对应的点表");
//            }
//            Long pdTypeId = analogs.getTypeId();
//            alarmType = alarmTypeService.findByPointDataTypeId(pdTypeId);
//            if (alarmType == null) {
//                throw new ObjectNotFoundException("找不到点号"+ pointNumber +"对应的告警事件类型");
//            }
//            Long alarmTypeId = alarmType.getId();
//            Long value = (long)entry.getValue().doubleValue();
//            String binaryValue = Long.toBinaryString(value);
//            char[] charArray = binaryValue.toCharArray();
//            List<String> list = new ArrayList<>();
//            for (char c : charArray) {
//                list.add(String.valueOf(c));
//            }
//            List<String> stringList = new ArrayList<>();
//            for (int i = 0, size = list.size(); i < size; i ++) {
//                if ("1".equals(list.get(i)) && getAlarmStatusByTypeAndBit(alarmTypeId, size - 1 - i) != null) {
//                    stringList.add(getAlarmStatusByTypeAndBit(alarmTypeId, size - 1 - i).getTitle());
//                } else if ("1".equals(list.get(i)) && getAlarmStatusByTypeAndBit(alarmTypeId, size - 1 - i) == null) {
//                    AlarmStatus status = getAlarmStatusByPointDataTypeCode(pdTypeId);
//                    if (status != null) {
//                        stringList.add(status.getTitle());
//                    }
//                }
//            }
//            results.put(entry.getKey(), stringList);
//        }
//        return results;
//    }
//
//    /**
//     * 根据告警类型和告警位获取告警规则
//     * @param alarmTypeId 告警类型ID
//     * @param bit 告警位
//     */
//    private AlarmStatus getAlarmStatusByTypeAndBit(Long alarmTypeId, Integer bit) {
//        return alarmStatusRepository.findByTypeAndBit(alarmTypeId, bit);
//    }
//
//    private AlarmStatus getAlarmStatusByPointDataTypeCode(Long typeId) {
//        return alarmStatusRepository.findByTypeId(typeId);
//    }
//
//    /**
//     * 查询全部对应的告警规则
//     */
//    @Override
//    public Map<Long, Map<Long, String>> findAll() {
//        Map<Long, Map<Long, String>> results = new HashMap<>();
//        Iterable<Map<String, Object>> list =  alarmStatusRepository.findAlarmStatuses();
//        for (Map<String, Object> alarmStatus : list) {
//            AlarmStatus status = map2AlarmStatus(alarmStatus);
//            if (results.containsKey(status.getCode())) {
//                results.get(status.getCode()).put(status.getBit(), status.getTitle());
//            } else {
//                Map<Long, String> map = new HashMap<>();
//                map.put(status.getBit(), status.getTitle());
//                results.put(Long.valueOf(status.getCode()), map);
//            }
//        }
//        return results;
//    }
//
//    @Override
//    public String getFormat(Long id) {
//        return alarmStatusRepository.getFormat(id);
//    }
//
//    @Override
//    public Double getRealValue(Long id) {
//        List<Long> pointNumbers = alarmStatusRepository.getAlarmAnalog(id);
//        Double max = 0D;
//        if (pointNumbers.size() > 0) {
//            Long firstPn = pointNumbers.get(0);
//            Map<Long, Double> map = measRealtimeClient.getMeasureRealtime(Arrays.asList(firstPn)).getBody().getResults();
//            max = map.get(firstPn);
//            for (Long tempPn : pointNumbers) {
////                Long tempPn = ParamUtil.getLong(a, "pointNumber");
////                Long tempPn = a.getPointNumber();
//                Map<Long, Double> realtime = measRealtimeClient.getMeasureRealtime(Arrays.asList(tempPn)).getBody().getResults();
//                Double temp = realtime.get(tempPn);
//                if (temp > max) {
//                    max = temp;
//                }
//            }
//        }
//        return max;
//    }
//
//    @Override
//    public String getTypeById(Long id) {
//        return alarmStatusRepository.getTypeById(id);
//    }
//
//    /**
//     * 批量更新告警级别
//     * @param alarmLevelId 告警级别代码
//     * @param idList 异常名称ID列表
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    @CacheEvict(value = CacheConsts.Region.ALARM_STATUS, allEntries = true)
//    public void updateAlarmLevel(Long alarmLevelId, List<Long> idList) {
//        alarmStatusRepository.updateAlarmLevel(alarmLevelId, idList);
//    }
//
//    private AlarmStatus map2AlarmStatus(Map<String, Object> map) {
//        if (map == null || map.size() == 0) {
//            return null;
//        }
//        try {
//            Class<AlarmStatus> statusClass = AlarmStatus.class;
//            AlarmStatus alarmStatus = statusClass.newInstance();
//            Field[] fields = statusClass.getDeclaredFields();
//            for (Field field : fields) {
//                field.setAccessible(true);
//                String name = field.getName();
//                for (Map.Entry<String, Object> entry : map.entrySet()) {
//                    if (entry.getKey().equalsIgnoreCase(name)) {
//                        field.set(alarmStatus, entry.getValue());
//                        break;
//                    }
//                }
//            }
//            return alarmStatus;
//        } catch (IllegalAccessException | InstantiationException e) {
//            return null;
//        }
//    }
//}
